System.Drawing var input = 277678; // part 1 Func FindPos = i => { var gs = (int)(Math.Ceiling(Math.Sqrt(i))); var offset = (int)(Math.Floor((double)gs / 2)); if (gs % 2 == 0) gs++; var br = gs * gs; var bl = br - (gs - 1); var tl = bl - (gs - 1); var tr = tl - (gs - 1); if (i >= bl) return new Point { X = i - br + offset, Y = -offset }; if (i >= tl) return new Point { X = -offset, Y = tl - i + offset }; if (i >= tr) return new Point { X = tr - i + offset, Y = offset }; return new Point { X = offset, Y = i - tr + offset }; }; var position = FindPos(input); var part1 = Math.Abs(position.X) + Math.Abs(position.Y); part1.Dump(); // part 2 var grid = new Dictionary(); Func GetValue = (x, y) => grid.TryGetValue(new Point(x, y), out int r) ? r : 0; grid.Add(new Point(0, 0), 1); while (grid.Values.Max() < input) { var pos = FindPos(grid.Count() + 1); var val = GetValue(pos.X - 1, pos.Y - 1) + GetValue(pos.X, pos.Y - 1) + GetValue(pos.X + 1, pos.Y - 1) + GetValue(pos.X - 1, pos.Y + 1) + GetValue(pos.X, pos.Y + 1) + GetValue(pos.X + 1, pos.Y + 1) + GetValue(pos.X - 1, pos.Y) + GetValue(pos.X + 1, pos.Y); grid.Add(pos, val); }; var part2 = grid.Values.Max(); part2.Dump();